package com.ztman.service.work.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.JsonObject;
import com.ztman.basic.annotation.log.SysLog;
import com.ztman.basic.base.R;
import com.ztman.basic.base.request.PageParams;
import com.ztman.basic.context.ContextUtil;
import com.ztman.basic.exception.BizException;
import com.ztman.basic.utils.DateUtils;
import com.ztman.service.authority.entity.auth.User;
import com.ztman.service.authority.entity.auth.UserRole;
import com.ztman.service.authority.service.auth.RoleService;
import com.ztman.service.authority.service.auth.UserRoleService;
import com.ztman.service.authority.service.auth.UserService;
import com.ztman.service.authority.service.core.OrgService;
import com.ztman.service.authority.service.core.StationService;
import com.ztman.service.work.dto.*;
import com.ztman.service.work.entity.*;
import com.ztman.service.work.service.*;
import com.ztman.service.work.vo.HandleParamVO;
import com.ztman.service.work.vo.InversionParamVO;
import com.ztman.service.work.vo.StateVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static cn.hutool.core.bean.BeanUtil.toBean;

/**
 * @author: wsd
 * @date: 2021/8/22 10:21
 */
@Slf4j
@Validated
@Api(value = "Work", tags = "工作流")
@SysLog(enabled = false)
@RestController
@RequestMapping("/api/v1")
public class WorkApiController {
    @Autowired
    private ProcessClassifyService processClassifyService;
    @Autowired
    private ProcessInfoService processInfoService;
    @Autowired
    private WorkOrderTplDataService workOrderTplDataService;
    @Autowired
    private WorkOrderInfoService workOrderInfoService;
    @Autowired
    private WorkOrderCirculationHistoryService workOrderCirculationHistoryService;
    @Autowired
    private TplInfoService tplInfoService;
    @Autowired
    private TaskInfoService taskInfoService;
    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private StationService stationService;
    @Autowired
    private OrgService orgService;
    @Autowired
    private RoleService roleService;


/*********************************************************流程后台管理接口--开始--*****************************************************************/
    /**
     * 流程分类
     * 分类分页
     *
     * @param params
     * @return R
     */
    @PostMapping("/classify/query")
    @ApiOperation(value = "分类分页", notes = "分类分页")
    public R classify(@RequestBody @Validated PageParams<ProcessClassifyPageQuery> params) {
        IPage<ProcessClassifyPageQuery> page = params.buildPage();
        ProcessClassifyPageQuery model = params.getModel();
        model.setDelFlag(false);

        processClassifyService.pageType(page, model);
        return R.success(page);
    }

    /**
     * 流程分类
     * 分类新增
     *
     * @param
     * @return R
     */
    @PostMapping("/classify")
    @ApiOperation(value = "分类新增", notes = "分类新增")
    public R classify(@RequestBody @Validated ProcessClassifySaveDTO processClassifySaveDTO) {
        ProcessClassify processClassify = new ProcessClassify();
        processClassifySaveDTO.setDelFlag(false);
        processClassifySaveDTO.setState(true);
        BeanUtils.copyProperties(processClassifySaveDTO, processClassify);
        boolean b = processClassifyService.save(processClassify);
        if (b) {
            return R.success();
        }
        return R.fail("新增失败");
    }

    /**
     * 流程分类
     * 分类修改
     *
     * @param processClassifyUpdateDTO
     * @return R
     */
    @PutMapping("/classify")
    @ApiOperation(value = "分类修改", notes = "分类修改")
    public R classify(@RequestBody @Validated ProcessClassifyUpdateDTO processClassifyUpdateDTO) {
        ProcessClassify processClassify = new ProcessClassify();
        BeanUtils.copyProperties(processClassifyUpdateDTO, processClassify);
        boolean b = processClassifyService.updateById(processClassify);
        if (b) {
            return R.success();
        }
        return R.fail("修改失败");
    }

    /**
     * 流程分类
     * 分类删除
     *
     * @param id
     * @return R
     */
    @DeleteMapping("/classify")
    @ApiOperation(value = "分类删除", notes = "分类删除")
    public R classify(@RequestParam("id") Long id) {
        ProcessClassify processClassify = new ProcessClassify();
        processClassify.setId(id);
        processClassify.setDelFlag(true);
        boolean b = processClassifyService.updateById(processClassify);
        if (b) {
            return R.success();
        }
        return R.fail("删除");
    }

    /**
     * 模板管理
     * 模板分页
     *
     * @param params
     * @return R
     */
    @PostMapping("/tpl/query")
    @ApiOperation(value = "模板分页", notes = "模板分页")
    public R tpl(@RequestBody @Validated PageParams<TplInfoPageQuery> params) {
        IPage<TplInfoPageQuery> page = params.buildPage();
        tplInfoService.pageType(page, params.getModel());
        return R.success(page);
    }

    /**
     * 模板管理
     * 模板详情
     *
     * @param id
     * @return R
     */
    @GetMapping("/tpl/details")
    @ApiOperation(value = "模板详情", notes = "模板详情")
    public R tplDeteils(@RequestParam Long id) {
        TplInfo byId = tplInfoService.getOne(new QueryWrapper<>(new TplInfo()).eq("id", id));
        return R.success(byId);
    }

    /**
     * 模板管理
     * 模板新增
     *
     * @param
     * @return R
     */
    @PostMapping("/tpl/clone/{id}")
    @ApiOperation(value = "模板新增", notes = "模板新增")
    public R tplClone(@PathVariable Long id) {
        if (id != null) {
            TplInfo tplInfo = tplInfoService.getById(id);
            if (tplInfo != null) {
                TplInfo tplInfo_new = toBean(tplInfo, TplInfo.class);
                tplInfo_new.setId(null);
                tplInfo_new.setName(tplInfo.getName() + "-copy");
                boolean save = tplInfoService.save(tplInfo_new);
                if (save) {
                    return R.success("克隆成功");
                }
            }
        }
        return R.fail("新增失败");
    }

    /**
     * 模板管理
     * 模板新增
     *
     * @param
     * @return R
     */
    @PostMapping("/tpl")
    @ApiOperation(value = "模板新增", notes = "模板新增")
    public R tpl(@RequestBody @Validated TplInfoSaveDTO tplInfoSaveDTO) {

        TplInfo tplInfo = new TplInfo();
        BeanUtils.copyProperties(tplInfoSaveDTO, tplInfo);
        tplInfo.setDelFlag(false);
        tplInfo.setState(true);
        tplInfo.setCreateTime(LocalDateTime.now());
        tplInfo.setCreatedBy(ContextUtil.getUserId());
        boolean b = tplInfoService.save(tplInfo);
        if (b) {
            return R.success();
        }
        return R.fail("新增失败");
    }

    /**
     * 模板修改
     *
     * @param tplInfoUpdateDTO
     * @return R
     */
    @PutMapping("/tpl")
    @ApiOperation(value = "模板修改", notes = "分模板修改")
    public R tpl(@RequestBody @Validated TplInfo tplInfoUpdateDTO) {
        boolean b = tplInfoService.updateById(tplInfoUpdateDTO);
        if (b) {
            return R.success();
        }
        return R.fail("修改失败");
    }

    /**
     * 模板管理
     * 模板删除
     *
     * @param id
     * @return R
     */
    @DeleteMapping("/tpl")
    @ApiOperation(value = "模板删除", notes = "模板删除")
    public R tpl(@RequestParam("id") Long id) {
        TplInfo tplInfo = new TplInfo();
        tplInfo.setId(id);
        tplInfo.setDelFlag(true);
        boolean b = tplInfoService.updateById(tplInfo);
        if (b) {
            return R.success(b, "流程删除成功");
        }
        return R.fail("删除失败");
    }


    /**
     * 流程管理
     * 流程分页
     *
     * @param params
     * @return R
     */
    @PostMapping("/process/query")
    @ApiOperation(value = "流程分页", notes = "流程分页")
    public R ProcessInfo(@RequestBody @Validated PageParams<ProcessInfoPageQuery> params) {
        IPage<ProcessInfoPageQuery> page = params.buildPage();
        processInfoService.pageType(page, params.getModel());
        return R.success(page);
    }

    /**
     * 流程管理
     * 流程详情
     *
     * @param id
     * @return R
     */
    @GetMapping("/process/details")
    @ApiOperation(value = "流程详情", notes = "流程详情")
    public R ProcessInfoDetails(@RequestParam Long id) {
        ProcessInfo byId = processInfoService.getById(id);
        return R.success(byId);
    }

    /**
     * 流程管理
     * 流程新增
     *
     * @param params
     * @return R
     */
    @PostMapping("/process")
    @ApiOperation(value = "流程新增", notes = "流程新增")
    public R ProcessInfoSave(@RequestBody @Validated ProcessInfo params) {
        params.setDelFlag(false);
        params.setId(null);
        return R.success(processInfoService.save(params));
    }

    /**
     * 流程管理
     * 流程拷贝
     *
     * @param id
     * @return R
     */
    @GetMapping("/process/clone/{id}")
    @ApiOperation(value = "流程拷贝", notes = "流程拷贝")
    public R ProcessInfoSave(@PathVariable Long id) {
        ProcessInfo processInfo = processInfoService.getById(id);
        String name = processInfo.getName();
        ProcessInfo processInfo_now = new ProcessInfo();
        BeanUtils.copyProperties(processInfo, processInfo_now);
        processInfo_now.setId(null);
        processInfo_now.setName(name + "-copy");
        processInfo_now.setCreatedBy(ContextUtil.getUserId());
        processInfo_now.setCreateTime(LocalDateTime.now());
        return R.success(processInfoService.save(processInfo_now));
    }

    /**
     * 流程管理
     * 流程修改
     *
     * @param params
     * @return R
     */
    @PutMapping("/process")
    @ApiOperation(value = "流程修改", notes = "流程修改")
    public R ProcessInfoUpdate(@RequestBody @Validated ProcessInfo params) {
        params.setUpdatedBy(ContextUtil.getUserId());
        params.setUpdateTime(LocalDateTime.now());
        return R.success(processInfoService.updateById(params));
    }

    /**
     * 流程管理
     * 流程删除
     *
     * @param id
     * @return R
     */
    @DeleteMapping("/process")
    @ApiOperation(value = "流程删除", notes = "流程删除")
    public R ProcessInfoDel(Long id) {
        ProcessInfoUpdateDTO params = new ProcessInfoUpdateDTO();
        params.setId(id);
        params.setDelFlag(true);
        return R.success(processInfoService.update(params));
    }

    /**
     * 流程任务管理
     * 流程任务分页
     *
     * @param params
     * @return R
     */
    @PostMapping("/task/query")
    @ApiOperation(value = " 流程任务分页", notes = " 流程任务分页")
    public R taskInfoPage(@RequestBody @Validated PageParams<TaskInfoPageQuery> params) {
        IPage<TaskInfoPageQuery> page = params.buildPage();
        taskInfoService.pageType(page, params.getModel());
        return R.success(page);
    }

    /**
     * 流程任务管理
     * 流程任务新增
     *
     * @param params
     * @return R
     */
    @PostMapping("/task")
    @ApiOperation(value = " 流程任务新增", notes = " 流程任务新增")
    public R taskInfoPage(@RequestBody TaskInfoSaveDTO params) {
        TaskInfo taskInfo = new TaskInfo();
        BeanUtils.copyProperties(params, taskInfo);
        taskInfo.setCreatedBy(ContextUtil.getUserId());
        taskInfo.setCreateTime(LocalDateTime.now());
        taskInfo.setState(true);
        taskInfo.setDelFlag(false);
        boolean save = taskInfoService.save(taskInfo);
        return R.success(save);
    }

    /**
     * 流程任务管理
     * 流程任务修改
     *
     * @param params
     * @return R
     */
    @PutMapping("/task")
    @ApiOperation(value = " 流程任务修改", notes = " 流程任务修改")
    public R taskInfoPage(@RequestBody TaskInfoUpdateDTO params) {
        TaskInfo taskInfo = toBean(params, TaskInfo.class);
        taskInfo.setUpdatedBy(ContextUtil.getUserId());
        taskInfo.setUpdateTime(LocalDateTime.now());
        boolean save = taskInfoService.updateById(taskInfo);
        return R.success(save);
    }

    /**
     * 流程任务管理
     * 流程任务删除
     *
     * @param id
     * @return R
     */
    @PutMapping("/task/{id}")
    @ApiOperation(value = " 流程任务删除", notes = " 流程任务删除")
    public R taskInfoPage(@PathVariable Long id) {
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.setUpdatedBy(ContextUtil.getUserId());
        taskInfo.setUpdateTime(LocalDateTime.now());
        taskInfo.setDelFlag(true);
        boolean save = taskInfoService.updateById(taskInfo);
        return R.success(save);
    }

    /**
     * 所有工单
     * 所有工单-删除
     *
     * @param id
     * @return R
     */
    @DeleteMapping("/work-order/delete/{id}")
    @ApiOperation(value = " 所有工单-删除", notes = " 所有工单-删除")
    @Transactional(rollbackFor = Exception.class)
    public R workOrderDelete(@PathVariable Long id) {
        // 查询工单信息
        WorkOrderInfoPageQuery workOrderInfoPageQuery = workOrderInfoService.getWorkOrderInfoById(id);
        WorkOrderInfo workOrderInfo = new WorkOrderInfo();
        BeanUtils.copyProperties(workOrderInfoPageQuery, workOrderInfo);
        if (workOrderInfo != null) {
            WorkOrderInfo workOrderInfoUpdate = new WorkOrderInfo();
            workOrderInfoUpdate.setId(id);
            workOrderInfoUpdate.setDelFlag(true);
            workOrderInfoService.updateById(workOrderInfoUpdate);
        }
        return R.success(true, "工单已删除");
    }

    /**
     * 所有工单
     * 所有工单-结单
     *
     * @param work_oroder_id
     * @return R
     */
    @PostMapping("/work-order/unity")
    @ApiOperation(value = " 所有工单-结单", notes = " 所有工单-结单")
    @Transactional(rollbackFor = Exception.class)
    public R workOrderUnity(@RequestParam Long work_oroder_id) {
        // 获取当前用户名称
        String name = ContextUtil.getName();

        // 查询工单信息
        WorkOrderInfoPageQuery workOrderInfoPageQuery = workOrderInfoService.getWorkOrderInfoById(work_oroder_id);
        WorkOrderInfo workOrderInfo = new WorkOrderInfo();
        BeanUtils.copyProperties(workOrderInfoPageQuery, workOrderInfo);
        if (workOrderInfo != null) {
            WorkOrderInfo workOrderInfoUpdate = new WorkOrderInfo();
            workOrderInfoUpdate.setId(workOrderInfo.getId());
            workOrderInfoUpdate.setIsEnd(1);
            // 序列化节点数据
            workOrderInfoService.updateById(workOrderInfoUpdate);
            WorkOrderCirculationHistory workHistory = new WorkOrderCirculationHistory();
            workHistory.setWorkOrder(work_oroder_id);
            workHistory.setTitle(workOrderInfo.getTitle());
            workHistory.setState("结束工单");
            workHistory.setCirculation("结单");
            workHistory.setProcessor(name);
            workHistory.setProcessorId(ContextUtil.getUserId());
            workHistory.setRemarks("手动结束工单。");
            workHistory.setStatus(2);
            workOrderCirculationHistoryService.save(workHistory);
        }
        return R.success(true, "工单已手动结单");
    }

    /**
     * 所有工单
     * 所有工单-转交
     *
     * @param paramVO
     * @return R
     */
    @PostMapping("/work-order/inversion")
    @ApiOperation(value = " 所有工单-转交", notes = " 所有工单-转交")
    @Transactional(rollbackFor = Exception.class)
    public R workOrderInversion(@RequestBody InversionParamVO paramVO) {
        System.out.println("paramVO = " + paramVO);
        // 获取当前用户名称
        String name = ContextUtil.getName();
        // 获取用户信息
        User user = userService.getById(paramVO.getUser_id());
        // 查询工单信息
        WorkOrderInfoPageQuery workOrderInfoPageQuery = workOrderInfoService.getWorkOrderInfoById(paramVO.getWork_order_id());
        // 序列化节点数据
        WorkOrderInfo workOrderInfo = new WorkOrderInfo();
        BeanUtils.copyProperties(workOrderInfoPageQuery, workOrderInfo);
        JSONArray stateJson = workOrderInfo.getState();
        workOrderInfo.setId(paramVO.getWork_order_id());
        JSONObject stateJsonObject = (JSONObject) stateJson.get(0);
        Long[] ids = {paramVO.getUser_id()};
        stateJsonObject.put("processor", ids);
        stateJsonObject.put("process_method", "person");
        workOrderInfoService.updateById(workOrderInfo);
        WorkOrderCirculationHistory workHistory = new WorkOrderCirculationHistory();
        workHistory.setWorkOrder(paramVO.getWork_order_id());
        workHistory.setTitle(workOrderInfo.getTitle());
        workHistory.setState(stateJsonObject.getString("label"));
        workHistory.setCirculation("转交");
        workHistory.setProcessor(name);
        workHistory.setProcessorId(ContextUtil.getUserId());
        workHistory.setRemarks(String.format("此阶段负责人已转交给《%s》", user.getName()));
        workHistory.setStatus(2);
        workHistory.setDelFlag(false);
        workOrderCirculationHistoryService.save(workHistory);
        return R.success(true, "工单已转交");
    }

    /**
     * 所有工单
     * 所有工单查看
     *
     * @param processId
     * @param workOrderId
     * @return R
     */
    @GetMapping("/work-order/process-structure")
    @ApiOperation(value = " 所有工单-查看", notes = " 所有工单-查看")
    public R workOrderDetails(@RequestParam Long processId, @RequestParam(required = false) Long workOrderId) {
        if (processId == null) {
            return R.fail("流程参数不正确");
        }
        if (workOrderId == null) {
            workOrderId = 0L;
        }
        StateController stateController = new StateController(tplInfoService, userService, userRoleService, workOrderInfoService, processInfoService, workOrderTplDataService, workOrderCirculationHistoryService);
        HashMap hashMap = stateController.ProcessStructure(processId, workOrderId);
        if (workOrderId != 0) {
            WorkOrderInfoPageQuery workOrderInfo = workOrderInfoService.getWorkOrderInfoById(workOrderId);
            Boolean userAuthority = stateController.JudgeUserAuthority(workOrderId, workOrderInfo.getCurrent_state());
            hashMap.put("userAuthority", userAuthority);
        }
        return R.success(hashMap);
    }

    /**
     * 工单
     * 工单-催办
     *
     * @param workOrderId
     * @return R
     */
    @GetMapping("/work-order/urge")
    @ApiOperation(value = " 工单-催办", notes = "工单-催办")
    public R workOrderUrge(@RequestParam Long workOrderId) {
        if (workOrderId == null || workOrderId == 0) {
            return R.fail("参数不正确，缺失workOrderId");
        }
        WorkOrderInfoPageQuery workOrderInfoPageQuery = workOrderInfoService.getWorkOrderInfoById(workOrderId);
        if (workOrderInfoPageQuery != null) {
            long time = System.currentTimeMillis();
            long urgeLastTime = workOrderInfoPageQuery.getUrgeLastTime();
            if (workOrderInfoPageQuery.getUrgeLastTime() != 0 && (time - urgeLastTime) <= 600) {
                return R.fail("十分钟内无法多次催办工单");
            }

            StateController stateController = new StateController(userService, userRoleService, roleService, orgService);
            List<User> sendToUserList = stateController.GetPrincipalUserInfo(workOrderInfoPageQuery.getState(), workOrderInfoPageQuery.getCreatedBy());
            //催办 方式 短信 邮件 系统消息 （待开发）

            WorkOrderInfo workOrderInfo = new WorkOrderInfo();
            workOrderInfo.setId(workOrderId);
            workOrderInfo.setUrgeLastTime(System.currentTimeMillis());
            workOrderInfo.setUrgeCount(workOrderInfoPageQuery.getUrgeCount() + 1);
            workOrderInfoService.updateById(workOrderInfo);
        }
        return R.success();
    }


    /**
     * 所有工单
     * 所有工单分页
     *
     * @param params
     * @return R
     */
    @PostMapping("/work-order/list")
    @ApiOperation(value = " 所有工单-分页", notes = " 所有工单-分页")
    public R workOrderList(@RequestBody @Validated PageParams<WorkOrderInfoPageQuery> params) {
        Long classify = params.getModel().getClassify();
        WorkOrderInfoPageQuery model = params.getModel();
        IPage<Object> page = params.buildPage();
        if (classify == null) {
            return R.fail("参数错误，请确认classify是否传递");
        }
        if (params.getModel().getProcessor() != null && classify != 1) {
            User user = userService.getById(model.getProcessor());
            UserRole userRoleParam = new UserRole();
            userRoleParam.setUserId(Long.valueOf(model.getProcessor()));
            List<UserRole> list = userRoleService.list(new QueryWrapper(UserRole
                    .builder()
                    .userId(user.getId())
                    .build()));
            List<Long> roleList = list.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            model.setUserId(String.valueOf(user.getId()));
            String[] longs = new String[roleList.size()];
            for (int i = 0; i < longs.length; i++) {
                longs[i] = String.valueOf(roleList.get(i));
            }
            model.setRoleIds(longs);
            model.setDeptId(user.getOrg().getKey());
        }
        if (classify == 1) {
            Long userId = ContextUtil.getUserId();
            User user = userService.getById(userId);
            UserRole userRoleParam = new UserRole();
            userRoleParam.setUserId(Long.valueOf(userId));
            List<UserRole> list = userRoleService.list(new QueryWrapper(UserRole
                    .builder()
                    .userId(userId)
                    .build()));
            List<Long> roleList = list.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            model.setUserId(String.valueOf(user.getId()));
            String[] longs = new String[roleList.size()];
            for (int i = 0; i < longs.length; i++) {
                longs[i] = String.valueOf(roleList.get(i));
            }
            model.setRoleIds(longs);
            model.setDeptId(user.getOrg().getKey());
        } else if (classify == 2) {
            model.setId(ContextUtil.getUserId());
        } else if (classify == 3) {
            model.setId(ContextUtil.getUserId());
        } else if (classify == 4) {
            // 所有工单
        }
        IPage<WorkOrderInfoPageQuery> result = workOrderInfoService.pageType(page, params.getModel());
        List<WorkOrderInfoPageQuery> records = result.getRecords();
        for (WorkOrderInfoPageQuery wo : records) {
            JSONArray state = wo.getState();
            List nameList = new ArrayList();
            StateVO stateVO = JSONObject.toJavaObject((JSONObject) state.get(0), StateVO.class);
            wo.setState_name(stateVO.getLabel());
            if (StringUtils.isNotEmpty(stateVO.getProcess_method()) && stateVO.getProcessor() != null && stateVO.getProcessor().length > 0) {
                nameList = new StateController(userService, roleService, orgService).getUserArrayName(stateVO.getProcessor(), stateVO.getProcess_method());
                wo.setPrincipals(StringUtils.join(nameList, ","));
            }
            wo.setData_classify(wo.getClassify());
        }
        return R.success(page);
    }

/*********************************************************流程后台管理接口--结束--*****************************************************************/

    /**
     * 主动接单
     *
     * @param id
     * @return R
     */
    @GetMapping("/work-order/active-order/{id}")
    @ApiOperation(value = "主动接单", notes = "主动接单")
    public R workOrderActiveOrder(@PathVariable Long id) {
        WorkOrderInfoPageQuery workOrderInfoById = workOrderInfoService.getWorkOrderInfoById(id);
        if (workOrderInfoById != null) {
            JSONArray state = workOrderInfoById.getState();
            if (state != null) {
                JSONObject jsonObject = state.getJSONObject(0);
                jsonObject.put("process_method", "person");
                Long[] userIds = {ContextUtil.getUserId()};
                jsonObject.put("processor", userIds);
                WorkOrderInfo workOrderInfo = BeanUtil.toBean(workOrderInfoById, WorkOrderInfo.class);
                System.out.println(workOrderInfo);
                workOrderInfo.setId(id);
                workOrderInfoService.updateById(workOrderInfo);
            }
        }
        return R.success(true, "接单成功，请及时处理");
    }

    /**
     * 新建工单
     *
     * @param saveDTO
     * @return R
     */
    @PostMapping("/work-order/create")
    @ApiOperation(value = "新建工单", notes = "新建工单")
    @Transactional
    public R CreateWorkOrder(@RequestBody WorkOrderInfoSaveDTO saveDTO) {
        WorkOrderInfo workOrderInfoValue = new WorkOrderInfo();
        BeanUtils.copyProperties(saveDTO, workOrderInfoValue);
        Long founder = ContextUtil.getUserId();
        // 获取变量值
        StateController variableValueState = new StateController(userService, orgService);
        JSONArray variableValue = saveDTO.getState();
        variableValueState.GetVariableValue(variableValue, founder);
        //查询流程信息
        ProcessInfo processInfo = ProcessInfo.builder().id(saveDTO.getProcess()).delFlag(false).build();
        ProcessInfo processValue = processInfoService.getOne(new QueryWrapper<ProcessInfo>(processInfo));
        JSONObject processValueStructure = processValue.getStructure();

        // 存储需要发送邮件的node
        JSONObject currentNode = new JSONObject();
        for (int i = 0; i < processValueStructure.getJSONArray("nodes").size(); i++) {
            JSONObject nodes = processValueStructure.getJSONArray("nodes").getJSONObject(i);
            if ("start".equals(nodes.getString("clazz"))) {
                currentNode = nodes;
            }
        }
        ProcessState processState = new ProcessState(processValueStructure.getJSONArray("nodes"));
        JSONObject nodeValue = processState.getNode(variableValue.getJSONObject(0).getString("id"));
        JSONArray form_data = saveDTO.getTpls().getJSONArray("form_data");
        Handle handle = new Handle();
        for (int i = 0; i < form_data.size(); i++) {
            handle.workOrderData.add(form_data.getJSONObject(i));
        }
        switch (nodeValue.getString("clazz")) {
            //排他网关
            case "exclusiveGateway":
                JSONArray sourceEdges = processState.getEdge(nodeValue.getString("id"), "source");
                if (sourceEdges == null || sourceEdges.size() <= 0) {
                    return R.fail("排他网关异常");
                }
                Boolean condExprStatus = false;
                breakTag:
                for (int i = 0; i < sourceEdges.size(); i++) {
                    JSONObject edge = sourceEdges.getJSONObject(i);
                    JSONArray edgeCondExpr = edge.getJSONArray("conditionExpression");
                    for (int j = 0; j < edgeCondExpr.size(); j++) {
                        JSONObject condExpr = edgeCondExpr.getJSONObject(j);
                        condExprStatus = handle.ConditionalJudgment(condExpr);
                        if (condExprStatus == null) {
                            return R.fail("条件为空");
                        } else if (condExprStatus) {
                            //进行节点跳转
                            nodeValue = processState.getNode(edge.getString("target"));
                            if ("userTask".equals(nodeValue.getString("clazz"))
                                    || "receiveTask".equals(nodeValue.getString("clazz"))) {
                                if (nodeValue.getString("assignValue") == null || "".equals(nodeValue.getString("assignValue"))) {
                                    new BizException("处理人不能为空");
                                }
                            }
                            variableValue.getJSONObject(0).put("id", nodeValue.getString("id"));
                            variableValue.getJSONObject(0).put("label", nodeValue.getString("label"));
                            variableValue.getJSONObject(0).put("processor", nodeValue.getJSONArray("assignValue"));
                            variableValue.getJSONObject(0).put("process_method", nodeValue.getString("assignType"));
                            break breakTag;
                        }
                    }
                }
                if (!condExprStatus) {
                    new BizException("所有流转均不符合条件，请确认。");
                }
                break;
            //并行网关
            case "parallelGateway":
                // 入口，判断
                JSONArray sourceEdges2 = processState.getEdge(nodeValue.getString("id"), "source");
                if (sourceEdges2.size() == 0) {
                    new BizException("查询流转信息失败");
                }
                nodeValue = processState.getNode(sourceEdges2.getJSONObject(0).getString("target"));

                JSONArray targetEdges = processState.getEdge(nodeValue.getString("id"), "target");
                if (targetEdges.size() == 0) {
                    new BizException("查询流转信息失败");
                }
                if (sourceEdges2.size() > 1 && targetEdges.size() == 1) {
                    //入口
                    variableValue = new JSONArray();
                    for (int i = 0; i < sourceEdges2.size(); i++) {
                        JSONObject edge = sourceEdges2.getJSONObject(i);
                        JSONObject targetStateValue = processState.getNode(edge.getString("target"));
                        JSONObject addMap = new JSONObject();
                        addMap.put("id", edge.getString("target"));
                        addMap.put("label", targetStateValue.getString("label"));
                        addMap.put("processor", targetStateValue.getString("assignValue"));
                        addMap.put("process_method", targetStateValue.getString("assignType"));
                        variableValue.add(addMap);
                    }

                } else {
                    new BizException("并行网关流程配置不正确");
                }
                break;
            default:
                break;
        }
        JSONArray relatePersonJsonArray = new JSONArray();
        relatePersonJsonArray.add(founder);
        // 获取变量值
        variableValueState.GetVariableValue(variableValue, founder);
        workOrderInfoValue.setState(variableValue);
        workOrderInfoValue.setCreateTime(LocalDateTime.now());
        workOrderInfoValue.setCreatedBy(founder);
        workOrderInfoValue.setDelFlag(false);
        workOrderInfoValue.setClassify(processValue.getClassifyId());
        workOrderInfoValue.setRelatedPerson(relatePersonJsonArray);
        boolean save = workOrderInfoService.save(workOrderInfoValue);
        if (!save) {
            throw new BizException("工单创建失败");
        }
        //创建工单模板关联数据
        JSONObject tpls = saveDTO.getTpls();
        JSONArray formStructure = tpls.getJSONArray("formStructure");
        for (int i = 0; i < formStructure.size(); i++) {
            JSONObject formData = form_data.getJSONObject(i);
            JSONObject formStructureObj = formStructure.getJSONObject(i);
            WorkOrderTplData addWorkOrderTplData = new WorkOrderTplData();
            addWorkOrderTplData.setWorkOrder(workOrderInfoValue.getId());
            addWorkOrderTplData.setFormData(formData);
            addWorkOrderTplData.setFormStructure(formStructureObj);
            addWorkOrderTplData.setCreatedBy(founder);
            addWorkOrderTplData.setDelFlag(false);
            addWorkOrderTplData.setCreateTime(LocalDateTime.now());
            boolean save1 = workOrderTplDataService.save(addWorkOrderTplData);
            if (!save1) {
                throw new BizException("创建工单模板关联数据失败");
            }
        }

        User user = userService.getById(founder);
        //创建历史记录
        JSONArray state = workOrderInfoValue.getState();
        WorkOrderCirculationHistory addHistory = new WorkOrderCirculationHistory();
        addHistory.setTitle(workOrderInfoValue.getTitle());
        addHistory.setWorkOrder(workOrderInfoValue.getId());
        addHistory.setState(saveDTO.getSource_state());
        addHistory.setSource(saveDTO.getSource());
        addHistory.setTarget(state.getJSONObject(0).getString("id"));
        addHistory.setCirculation("新建");
        addHistory.setProcessor(user.getName());
        addHistory.setProcessorId(user.getId());
        addHistory.setState("2");
        addHistory.setDelFlag(false);
        boolean saveHistory = workOrderCirculationHistoryService.save(addHistory);
        if (!saveHistory) {
            throw new BizException("新建历史记录失败");
        }
        // 更新流程提交数量统计
        ProcessInfo processInfoSubmit = processInfoService.getById(workOrderInfoValue.getProcess());
        ProcessInfo updateProcessInfoSubmitCount = new ProcessInfo();
        updateProcessInfoSubmitCount.setId(processInfoSubmit.getId());
        updateProcessInfoSubmitCount.setSubmitCount(processInfoSubmit.getSubmitCount() + 1);
        boolean updateProcessSubmitCount = processInfoService.updateById(updateProcessInfoSubmitCount);
        if (!updateProcessSubmitCount) {
            throw new BizException("更新提交数量统计失败");
        }
        //发送通知（未开发）
        // 执行任务 （未开发）
        return R.success(true);
    }


    /**
     * 重开工单
     *
     * @param id
     * @return R
     */
    @GetMapping("/work-order/reopen/{id}")
    @ApiOperation(value = "重开工单", notes = "重开工单")
    @Transactional
    public R ReopenWorkOrder(@PathVariable Long id) {

        WorkOrderInfoPageQuery workOrderInfoById = workOrderInfoService.getWorkOrderInfoById(id);
        Long userId = ContextUtil.getUserId();
        if (workOrderInfoById != null) {
            ProcessInfo processInfoById = processInfoService.getProcessInfoById(workOrderInfoById.getProcess());
            if (processInfoById != null) {
                JSONObject structure = processInfoById.getStructure();
                if (structure != null) {
                    JSONArray nodes = structure.getJSONArray("nodes");
                    String startId = "";
                    String label = "";
                    for (int i = 0; i < nodes.size(); i++) {
                        if ("start".equals(nodes.getJSONObject(i).getString("clazz"))) {
                            startId = nodes.getJSONObject(i).getString("id");
                            label = nodes.getJSONObject(i).getString("label");
                        }
                    }
                    JSONObject state = new JSONObject();
                    List<String> userIds = new ArrayList();
                    userIds.add(String.valueOf(userId));
                    state.put("id", startId);
                    state.put("label", label);
                    state.put("processor", userIds);
                    state.put("process_method", "person");
                    JSONArray jsonState = new JSONArray();
                    jsonState.add(state);
                    JSONArray relatedPerson = new JSONArray();
                    relatedPerson.add(userId);
                    WorkOrderInfo addWorkOrder = new WorkOrderInfo();
                    addWorkOrder.setTitle(workOrderInfoById.getTitle() + "-重开-" +new SimpleDateFormat("yyyy年MM月 HH:mm:ss").format(new Date()));
                    addWorkOrder.setPriority(workOrderInfoById.getPriority());
                    addWorkOrder.setProcess(workOrderInfoById.getProcess());
                    addWorkOrder.setClassify(workOrderInfoById.getClassify());
                    addWorkOrder.setState(jsonState);
                    addWorkOrder.setRelatedPerson(relatedPerson);
                    addWorkOrder.setCreatedBy(userId);
                    addWorkOrder.setDelFlag(false);
                    addWorkOrder.setCreateTime(LocalDateTime.now());
                    boolean save = workOrderInfoService.save(addWorkOrder);
                    if (!save) {
                        return R.fail("新建工单失败");
                    }
                    WorkOrderTplData workOrderTplData = new WorkOrderTplData();
                    workOrderTplData.setWorkOrder(id);
                    List<WorkOrderTplData> list = workOrderTplDataService.list(new QueryWrapper<>(workOrderTplData));
                    for (WorkOrderTplData tplData : list) {
                        tplData.setWorkOrder(addWorkOrder.getId());
                        tplData.setId(null);
                        boolean tplDataAdd = workOrderTplDataService.save(tplData);
                        if (!tplDataAdd) {
                            return R.fail("创建工单数据失败");
                        }
                    }
                    return R.success("工单已重开");
                }
            }

        }
        return R.fail("查询工单信息失败");
    }

    /**
     * 工单申请
     *
     * @param name
     * @return R
     */
    @GetMapping("/process/classify")
    @ApiOperation(value = "可申请工单查询", notes = "可申请工单查询")
    public R getProcessClassify(@RequestParam(required = false) String name) {
        ProcessClassify param = new ProcessClassify();
        param.setName(name);
        List<ProcessClassify> list = processClassifyService.list(new QueryWrapper<>(param));
        List<ProcessInfoPageQuery> resuleList = new ArrayList<>();
        for (ProcessClassify processClassify : list) {
            ProcessInfoPageQuery processInfoPageQuery = new ProcessInfoPageQuery();
            BeanUtils.copyProperties(processClassify, processInfoPageQuery);
            ProcessInfo processInfo = new ProcessInfo();
            processInfo.setClassifyId(processClassify.getId());
            List<ProcessInfo> list1 = processInfoService.list(new QueryWrapper<>(processInfo));
            processInfoPageQuery.setProcess_list(list1);
            resuleList.add(processInfoPageQuery);
        }
        return R.success(resuleList);
    }

    /**
     * 首页仪表盘
     *
     * @param start_time
     * @param end_time
     * @return R
     */
    @GetMapping("/dashboard")
    @ApiOperation(value = "首页仪表盘", notes = "首页仪表盘")
    public R dashboard(@Validated String start_time, @Validated String end_time) {
        Long userId = ContextUtil.getUserId();
        Date date0000 = null;
        Date date2359 = null;
        //默认七天的数据
        if (StringUtils.isEmpty(start_time) || StringUtils.isEmpty(end_time)) {
            date0000 = DateUtils.getDate0000(getPastDate(6));
            date2359 = DateUtils.getDate2359(new Date());
        } else {
            date0000 = DateUtils.getDate0000(DateUtils.parse(start_time, "yyyy-MM-dd"));
            date2359 = DateUtils.getDate2359(DateUtils.parse(end_time, "yyyy-MM-dd"));
        }
        //所有工单数据统计
        WorkOrderInfo workOrderInfo = new WorkOrderInfo();
        LambdaQueryWrapper<WorkOrderInfo> workOrderInfoLambdaQueryWrapper = new QueryWrapper<>(workOrderInfo).lambda()
                .between(WorkOrderInfo::getCreateTime, date0000, date2359)
                .eq(WorkOrderInfo::getDelFlag, false);
        int count = workOrderInfoService.count(workOrderInfoLambdaQueryWrapper);

        // 查询工单数据排名
        List<Map<String, Object>> workOrderRankCount = workOrderInfoService.workOrderRank(date0000, date2359);
        /*
工单提交数据统计
        Map<String, Object> dateRangeStatistics = workOrderInfoService.DateRangeStatistics(date0000, date2359);
*/
        // 处理工单人员排行榜
        List<Map<String, Object>> handlePersonRank = workOrderInfoService.HandlePersonRank(date0000, date2359);
        // // 工单处理耗时排行榜
        List<Map<String, Object>> handlePeriodRank = workOrderInfoService.HandlePeriodRank(date0000, date2359);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("count", count);
        resultMap.put("ranks", workOrderRankCount);
        resultMap.put("handle", handlePersonRank);
        resultMap.put("period", handlePeriodRank);
        resultMap.put("submit", "");
        return R.success(resultMap);
    }

    /**
     * 处理工单
     *
     * @param
     * @return R
     */
    @PostMapping("/work-order/handle")
    @ApiOperation(value = "处理工单", notes = "处理工单")
    @Transactional
    public R ProcessWorkOrder(@RequestBody HandleParamVO handleParamVO) {
        //处理工单
        StateController stateController = new StateController(tplInfoService, userService, userRoleService, workOrderInfoService, processInfoService, workOrderTplDataService, workOrderCirculationHistoryService);
        Long work_order_id = handleParamVO.getWork_order_id();
        if (work_order_id != null && work_order_id != 0) {
//            WorkOrderInfoPageQuery workOrderInfo = workOrderInfoService.getWorkOrderInfoById(work_order_id);
            Boolean userAuthority = stateController.JudgeUserAuthority(work_order_id, handleParamVO.getSource_state());
            if (!userAuthority) {
                return R.fail("当前用户没有权限进行此操作");
            }
            Handle handle = new Handle(workOrderCirculationHistoryService, workOrderInfoService, processInfoService, workOrderTplDataService, userService, orgService, userRoleService);
            handle.HandleWorkOrder(handleParamVO);
        }
        return R.success();
    }


    public static Date getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String result = format.format(today);
        return today;
    }
}
